package com.zlq.cn.service.ai;

import cn.hutool.core.lang.Pair;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Sets;
import com.zlq.cn.api.ApiCodeEnum;
import com.zlq.cn.api.ResponseException;
import com.zlq.cn.bootstrap.SignApiBootstrap;
import com.zlq.cn.dto.vo.SignCommonParam;
import com.zlq.cn.entity.FanyiUser;
import com.zlq.cn.entity.YoudaoCorrectWriting;
import com.zlq.cn.mapper.ai.YoudaoCorrectWritingMapper;
import com.zlq.cn.service.un.ConfigService;
import com.zlq.cn.service.un.FanyiUserService;
import com.zlq.cn.util.AuthV3Util;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 右道批改作文 服务实现类
 * </p>
 *
 * @author zhoucl
 * @since 2023-09-21
 */
@Slf4j
@Service
public class YoudaoCorrectWritingService extends ServiceImpl<YoudaoCorrectWritingMapper, YoudaoCorrectWriting> {
    private static final Map<String, Pair<String, String>> KEY_SECRET = new HashMap<>();
    private static final String YIPAISOUTI = "com.silerzero.yipaisouti";
    private static final Set<String> PASS_PACKAGE_NAME = Sets.newHashSet(YIPAISOUTI);
    private static final Map<String, String> ERROR_CODE = new HashMap<>();

    static {
        KEY_SECRET.put("correct_writing_cn_image", Pair.of("402ec6c3ba9aa776", "j8c4X3HMC3xeGiAaX2DHpKw7rPis31AW"));
        KEY_SECRET.put("correct_writing_cn_text", Pair.of("402ec6c3ba9aa776", "j8c4X3HMC3xeGiAaX2DHpKw7rPis31AW"));
        KEY_SECRET.put("ocr_writing_erase", Pair.of("4f13f13187c6e592", "ryxo9ZD7rjJ2n6oSSF5keHGNU0yIz7hC"));
        KEY_SECRET.put("ocrquestionapi", Pair.of("73c04e27e4b0e78b", "dpAUyBRXqzNmSybmiZe9ILl8nBcvOpc2"));
        KEY_SECRET.put("getPinYin", Pair.of("040497244ec41dc1", "qQ4AQJTnnGfPV0qRwCJS07d4ISJFzBoR"));
        initErrorCode();
    }

    @Resource
    private ConfigService configService;
    @Resource
    private FanyiUserService fanyiUserService;

    @SneakyThrows
    public YoudaoCorrectWriting openapi(HashMap<String, Object> param) {
        FanyiUser fanyiUser = SignApiBootstrap.requestFanYiUser();
        SignCommonParam signCommonParam = SignApiBootstrap.get();
        Integer freeNumber = ObjectUtils.defaultIfNull(fanyiUser.getFreeNumber(), 1);
//        if (!PASS_PACKAGE_NAME.contains(signCommonParam.getPackageName())) {

        if (!fanyiUser.isVip()) {
            ResponseException.resultError("888", "升级VIP尊享全部功能");
        }

//        }
//        if (YIPAISOUTI.equals(signCommonParam.getPackageName()) && !fanyiUser.isVip() && freeNumber > 1) {
//            ResponseException.resultError("888", "请先开通VIP！");
//        }
        String type = param.getOrDefault("type", "").toString();
        Assert.state(StringUtils.isNotEmpty(type), "类型不能为空");
        param.remove("type");
        param.remove("imei");
        param.remove("packageName");
        param.remove("timestamp");
        param.remove("version");
        Pair<String, String> pair = KEY_SECRET.get(type);
        AuthV3Util.addAuthParams(pair.getKey(), pair.getValue(), param);
        String url = "https://openapi.youdao.com/" + type;
        log.info("请求链接：" + url);
        log.info("请求参数：" + param);
        JSONObject jsonObject = JSON.parseObject(HttpUtil.post(url, param));
        log.info("响应参数：" + jsonObject);
        String errorCode = jsonObject.getString("errorCode");
        if ("0".equals(errorCode)) {
            YoudaoCorrectWriting youdaoCorrectWriting = new YoudaoCorrectWriting()
                    .setUserImei(fanyiUser.getFanyiUserImei())
                    .setTitle(param.getOrDefault("title", "").toString())
                    .setType(type)
                    .setCreateTime(LocalDateTime.now());
            if ("ocr_writing_erase".equals(type)) {
                JSONObject data = new JSONObject();
                data.put("originalImg", param.get("img"));
                byte[] decode = jsonObject.getBytes("eraseEnhanceImg");
                data.put("eraseEnhanceImg", configService.putObject("youdao/ocr_writing_erase", TencentAiService.createBeforeImage(), ".png", decode));
                youdaoCorrectWriting.setData(data.toJSONString());
            } else {
                youdaoCorrectWriting.setData(StringUtils.defaultIfBlank(jsonObject.getString("Result"), jsonObject.getString("data")));
            }
            super.save(youdaoCorrectWriting);
            fanyiUser.setFreeNumber(freeNumber);
            fanyiUserService.lambdaUpdate()
                    .set(FanyiUser::getFreeNumber, fanyiUser.getFreeNumber() + 1)
                    .eq(FanyiUser::getFanyiUserImei, fanyiUser.getFanyiUserImei())
                    .update();
            return youdaoCorrectWriting;
        }
        throw new ResponseException(ApiCodeEnum.API_ERROR.getCode(), ERROR_CODE.getOrDefault(errorCode, errorCode));
    }

    public Page<YoudaoCorrectWriting> list(Page page, YoudaoCorrectWriting param) {
        FanyiUser fanyiUser = SignApiBootstrap.requestFanYiUser();
        return super.lambdaQuery()
                .eq(YoudaoCorrectWriting::getUserImei, fanyiUser.getFanyiUserImei())
                .eq(YoudaoCorrectWriting::getType, param.getType())
                .like(StringUtils.isNotEmpty(param.getTitle()), YoudaoCorrectWriting::getTitle, param.getTitle())
                .page(page);
    }


    public static void initErrorCode() {
        ERROR_CODE.put("101", "缺少必填的参数");
        ERROR_CODE.put("102", "不支持的语言类型");
        ERROR_CODE.put("103", "翻译文本过长");
        ERROR_CODE.put("104", "不支持的API类型");
        ERROR_CODE.put("105", "不支持的签名类型");
        ERROR_CODE.put("106", "不支持的响应类型");
        ERROR_CODE.put("107", "不支持的传输加密类型");
        ERROR_CODE.put("108", "应用ID无效，注册账号，登录后台创建应用，可获得应用ID和应用密钥等信息");
        ERROR_CODE.put("109", "batchLog格式不正确");
        ERROR_CODE.put("110", "无相关服务的有效实例");
        ERROR_CODE.put("111", "开发者账号无效");
        ERROR_CODE.put("112", "请求服务无效");
        ERROR_CODE.put("113", "q不能为空");
        ERROR_CODE.put("114", "不支持的图片传输方式");
        ERROR_CODE.put("201", "解密失败，可能为DES, BASE64, URLDecode的错误");
        ERROR_CODE.put("202", "签名检验失败");
        ERROR_CODE.put("203", "访问IP地址不在可访问IP列表");
        ERROR_CODE.put("205", "请求的接口与应用的平台类型不一致，如有疑问请参考入门指南");
        ERROR_CODE.put("206", "因为时间戳无效导致签名校验失败");
        ERROR_CODE.put("207", "重放请求");
        ERROR_CODE.put("301", "辞典查询失败");
        ERROR_CODE.put("302", "翻译查询失败");
        ERROR_CODE.put("303", "服务端的其它异常");
        ERROR_CODE.put("304", "会话闲置太久超时");
        ERROR_CODE.put("401", "账户已经欠费停");
        ERROR_CODE.put("402", "offlinesdk不可用");
        ERROR_CODE.put("411", "访问频率受限, 请稍后访问");
        ERROR_CODE.put("412", "长请求过于频繁，请稍后访问");
        ERROR_CODE.put("1001", "无效的OCR类型");
        ERROR_CODE.put("1002", "不支持的OCR image类型");
        ERROR_CODE.put("1003", "不支持的OCR Language类型");
        ERROR_CODE.put("1004", "识别图片过大");
        ERROR_CODE.put("1201", "图片base64解密失败");
        ERROR_CODE.put("1301", "OCR段落识别失败");
        ERROR_CODE.put("1411", "访问频率受限");
        ERROR_CODE.put("1412", "超过最大识别字节数");
        ERROR_CODE.put("2003", "不支持的语言识别Language类型");
        ERROR_CODE.put("2004", "合成字符过长");
        ERROR_CODE.put("2005", "不支持的音频文件类型");
        ERROR_CODE.put("2006", "不支持的发音类型");
        ERROR_CODE.put("2201", "解密失败");
        ERROR_CODE.put("2301", "服务的异常");
        ERROR_CODE.put("2411", "访问频率受限, 请稍后访问");
        ERROR_CODE.put("2412", "超过最大请求字符数");
        ERROR_CODE.put("3001", "不支持的语音格式");
        ERROR_CODE.put("3002", "不支持的语音采样率");
        ERROR_CODE.put("3003", "不支持的语音声道");
        ERROR_CODE.put("3004", "不支持的语音上传类型");
        ERROR_CODE.put("3005", "不支持的语言类型");
        ERROR_CODE.put("3006", "不支持的识别类型");
        ERROR_CODE.put("3007", "识别音频文件过大");
        ERROR_CODE.put("3008", "识别音频时长过长");
        ERROR_CODE.put("3009", "不支持的音频文件类型");
        ERROR_CODE.put("3010", "不支持的发音类型");
        ERROR_CODE.put("3201", "解密失败");
        ERROR_CODE.put("3301", "语音识别失败");
        ERROR_CODE.put("3302", "语音翻译失败");
        ERROR_CODE.put("3303", "服务的异常");
        ERROR_CODE.put("3411", "访问频率受限, 请稍后访问");
        ERROR_CODE.put("3412", "超过最大请求字符数");
        ERROR_CODE.put("4001", "不支持的语音识别格式");
        ERROR_CODE.put("4002", "不支持的语音识别采样率");
        ERROR_CODE.put("4003", "不支持的语音识别声道");
        ERROR_CODE.put("4004", "不支持的语音上传类型");
        ERROR_CODE.put("4005", "不支持的语言类型");
        ERROR_CODE.put("4006", "识别音频文件过大");
        ERROR_CODE.put("4007", "识别音频时长过长");
        ERROR_CODE.put("4201", "解密失败");
        ERROR_CODE.put("4301", "语音识别失败");
        ERROR_CODE.put("4303", "服务的异常");
        ERROR_CODE.put("4411", "访问频率受限, 请稍后访问");
        ERROR_CODE.put("4412", "超过最大请求时长");
        ERROR_CODE.put("5001", "无效的OCR类型");
        ERROR_CODE.put("5002", "不支持的OCR image类型");
        ERROR_CODE.put("5003", "不支持的语言类型");
        ERROR_CODE.put("5004", "识别图片过大");
        ERROR_CODE.put("5005", "不支持的图片类型");
        ERROR_CODE.put("5006", "文件为空");
        ERROR_CODE.put("5201", "解密错误，图片base64解密失败");
        ERROR_CODE.put("5301", "OCR段落识别失败");
        ERROR_CODE.put("5411", "访问频率受限");
        ERROR_CODE.put("5412", "超过最大识别流量");
        ERROR_CODE.put("9001", "不支持的语音格式");
        ERROR_CODE.put("9002", "不支持的语音采样率");
        ERROR_CODE.put("9003", "不支持的语音声道");
        ERROR_CODE.put("9004", "不支持的语音上传类型");
        ERROR_CODE.put("9005", "不支持的语音识别 Language类型");
        ERROR_CODE.put("9301", "ASR识别失败");
        ERROR_CODE.put("9303", "服务器内部错误");
        ERROR_CODE.put("9411", "访问频率受限（超过最大调用次数）");
        ERROR_CODE.put("9412", "超过最大处理语音长度");
        ERROR_CODE.put("10001", "无效的OCR类型");
        ERROR_CODE.put("10002", "不支持的OCR image类型");
        ERROR_CODE.put("10004", "识别图片过大");
        ERROR_CODE.put("10201", "图片base64解密失败");
        ERROR_CODE.put("10301", "OCR段落识别失败");
        ERROR_CODE.put("10411", "访问频率受限");
        ERROR_CODE.put("10412", "超过最大识别流量");
        ERROR_CODE.put("11001", "不支持的语音识别格式");
        ERROR_CODE.put("11002", "不支持的语音识别采样率");
        ERROR_CODE.put("11003", "不支持的语音识别声道");
        ERROR_CODE.put("11004", "不支持的语音上传类型");
        ERROR_CODE.put("11005", "不支持的语言类型");
        ERROR_CODE.put("11006", "识别音频文件过大");
        ERROR_CODE.put("11007", "识别音频时长过长，最大支持30s");
        ERROR_CODE.put("11201", "解密失败");
        ERROR_CODE.put("11301", "语音识别失败");
        ERROR_CODE.put("11303", "服务的异常");
        ERROR_CODE.put("11411", "访问频率受限, 请稍后访问");
        ERROR_CODE.put("11412", "超过最大请求时长");
        ERROR_CODE.put("12001", "图片尺寸过大");
        ERROR_CODE.put("12002", "图片base64解密失败");
        ERROR_CODE.put("12003", "引擎服务器返回错误");
        ERROR_CODE.put("12004", "图片为空");
        ERROR_CODE.put("12005", "不支持的识别图片类型");
        ERROR_CODE.put("12006", "图片无匹配结果");
        ERROR_CODE.put("13001", "不支持的角度类型");
        ERROR_CODE.put("13002", "不支持的文件类型");
        ERROR_CODE.put("13003", "表格识别图片过大");
        ERROR_CODE.put("13004", "文件为空");
        ERROR_CODE.put("13301", "表格识别失败");
        ERROR_CODE.put("15001", "需要图片");
        ERROR_CODE.put("15002", "图片过大（1 M）");
        ERROR_CODE.put("15003", "服务调用失败");
        ERROR_CODE.put("17001", "需要图片");
        ERROR_CODE.put("17002", "图片过大（1 M）");
        ERROR_CODE.put("17003", "识别类型未找到");
        ERROR_CODE.put("17004", "不支持的识别类型");
        ERROR_CODE.put("17005", "服务调用失败");
    }
}
